home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------------------------
- wndproc.c
- 時計の改造
- KAZUBON 1997-1998
- -------------------------------------------------------*/
-
- #include "tcdll.h"
-
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
- void InitClock(HWND hwnd);
- void EndClock(void);
- BOOL IsIE4(HWND hwnd);
- HMENU CreateClockMenu(void);
- void CreateTip(HWND hwnd);
- void CreateClockDC(HWND hwnd);
- void ReadData(HWND hwnd);
- void OnTimer(HWND hwnd);
- void DrawClockSub(HWND hwnd, HDC hdc, SYSTEMTIME* pt);
- void DrawClock(HWND hwnd, HDC hdc);
- LRESULT OnCalcRect(HWND hwnd);
- void OnTooltipNeedText(UINT code, LPARAM lParam);
-
- /*------------------------------------------------
- 各プロセスで共通のデータ
- --------------------------------------------------*/
- #pragma data_seg(".MYDATA")
- HHOOK hhook = 0;
- HWND hwndTClockMain = NULL;
- HWND hwndClock = NULL;
- #pragma data_seg()
-
- /*------------------------------------------------
- Globals
- --------------------------------------------------*/
- HANDLE hmod = 0;
- WNDPROC oldWndProc = NULL;
- HDC hdcClock = NULL;
- HBITMAP hbmpClock = NULL;
- HFONT hFon = NULL;
- HMENU hMenu = NULL;
- HWND hwndTip = NULL;
- COLORREF colback, colfore;
- char format[1024];
- BOOL bHour12, bHourZero;
- int hourLast = -1, minuteLast = -1;
- BOOL bNoClock = FALSE;
- int nBlink = 0;
- int buttondown = 0;
- BOOL bStartMenuClock = FALSE;
- BOOL bIE4 = FALSE;
- char tooltip[80];
- int dvpos = 0, dheight = 0;
-
- extern HWND hwndStart;
- extern HWND hwndStartMenu;
-
- /*------------------------------------------------
- 時計の初期化
- --------------------------------------------------*/
- void InitClock(HWND hwnd)
- {
- BOOL b;
-
- hwndClock = hwnd;
-
- PostMessage(hwndTClockMain, WM_USER, 0, (LPARAM)hwnd);
-
- //レジストリ読み込み
- ReadData(hwndClock);
- //サブクラス化
- oldWndProc = (WNDPROC)GetWindowLong(hwndClock, GWL_WNDPROC);
- SetWindowLong(hwndClock, GWL_WNDPROC, (LONG)WndProc);
- //ダブルクリック受け付ける
- SetClassLong(hwndClock, GCL_STYLE,
- GetClassLong(hwndClock, GCL_STYLE) | CS_DBLCLKS);
- //スタートボタンの初期化
- SetStartButton(hwndClock);
- //スタートメニューの初期化
- SetStartMenu(hwndClock);
-
- //1秒おきにタイマをかける
- SetTimer(hwndClock, 1, 1000, NULL);
- //ツールチップ作成
- CreateTip(hwndClock);
-
- b = GetMyRegLong(NULL, "DropFiles", FALSE);
- DragAcceptFiles(hwnd, b);
-
- bIE4 = IsIE4(hwndClock);
-
- if(bIE4) InitStartMenuIE4();
-
- //タスクバーの更新
- PostMessage(GetParent(GetParent(hwndClock)), WM_SIZE,
- SIZE_RESTORED, 0);
- InvalidateRect(GetParent(GetParent(hwndClock)), NULL, TRUE);
- }
-
- /*------------------------------------------------
- 時計の終了処理
- --------------------------------------------------*/
- void DeleteClockRes(void)
- {
- if(hFon) DeleteObject(hFon); hFon = NULL;
- if(hdcClock) DeleteDC(hdcClock); hdcClock = NULL;
- if(hbmpClock) DeleteObject(hbmpClock); hbmpClock = NULL;
- ClearTimer();
- }
- void EndClock(void)
- {
- DragAcceptFiles(hwndClock, FALSE);
- if(hwndTip) DestroyWindow(hwndTip); hwndTip = NULL;
- EndStartButton();
- EndStartMenu();
- if(hMenu) DestroyMenu(hMenu); hMenu = NULL;
- ClearStartMenuIE4();
-
- DeleteClockRes();
-
- if(hwndClock && IsWindow(hwndClock))
- {
- KillTimer(hwndClock, 1);
- SetWindowLong(hwndClock, GWL_WNDPROC, (LONG)oldWndProc);
- oldWndProc = NULL;
- }
- //TClockウィンドウを終了させる
- if(IsWindow(hwndTClockMain))
- PostMessage(hwndTClockMain, WM_USER+2, 0, 0);
- }
-
- /*------------------------------------------------
- IE4かどうか
- --------------------------------------------------*/
- BOOL IsIE4(HWND hwnd)
- {
- char classname[80];
-
- hwnd = GetParent(GetParent(hwnd));
- if(hwnd == NULL) return FALSE;
- hwnd = GetWindow(hwnd, GW_CHILD);
- while(hwnd)
- {
- GetClassName(hwnd, classname, 80);
- if(lstrcmpi(classname, "ReBarWindow32") == 0)
- return TRUE;
- hwnd = GetWindow(hwnd, GW_HWNDNEXT);
- }
- return FALSE;
- }
-
- /*------------------------------------------------
- 時計ウィンドウのサブクラスプロシージャ
- --------------------------------------------------*/
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch(message) // ツールチップ対応
- {
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- case WM_MOUSEMOVE:
- {
- MSG msg;
- msg.hwnd = hwnd;
- msg.message = message;
- msg.wParam = wParam;
- msg.lParam = lParam;
- msg.time = GetMessageTime();
- msg.pt.x = LOWORD(GetMessagePos());
- msg.pt.y = HIWORD(GetMessagePos());
- if(hwndTip)
- SendMessage(hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
- }
- }
-
- switch(message)
- {
- case WM_DESTROY:
- DeleteClockRes();
- break;
- // 親ウィンドウから送られ、サイズを返すメッセージ
- case (WM_USER+100):
- if(bNoClock) break;
- return OnCalcRect(hwnd);
- // システムの設定を反映する
- case WM_SYSCOLORCHANGE:
- CreateClockDC(hwnd); //hdcClock作り直し
- case WM_WININICHANGE:
- case WM_TIMECHANGE:
- // 親ウィンドウから送られる
- case (WM_USER+101):
- {
- HDC hdc;
- if(bNoClock) break;
- hdc = GetDC(hwnd);
- DrawClock(hwnd, hdc);
- ReleaseDC(hwnd, hdc);
- return 0;
- }
- case WM_SIZE:
- CreateClockDC(hwnd); //hdcClock作り直し
- break;
- case WM_ERASEBKGND:
- break;
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdc;
- if(bNoClock) break;
- hdc = BeginPaint(hwnd, &ps);
- DrawClock(hwnd, hdc);
- EndPaint(hwnd, &ps);
- return 0;
- }
- case WM_TIMER:
- if(wParam == 1)
- {
- OnTimer(hwnd); return 0;
- }
- else
- {
- if(bNoClock) break;
- else return 0;
- }
- // マウスダウン
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- if(nBlink)
- {
- nBlink = 0; InvalidateRect(hwnd, NULL, TRUE);
- }
- if(message == WM_LBUTTONDOWN && bStartMenuClock &&
- hwndStart && IsWindow(hwndStart))
- {
- SetWindowPos(hwndStart, NULL, 0, 0, 0, 0,
- SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
- // スタートメニュー
- PostMessage(hwndStart, WM_LBUTTONDOWN, 0, 0);
- }
- buttondown = message;
- return 0;
- // マウスアップ
- case WM_LBUTTONUP:
- if(buttondown == WM_LBUTTONDOWN)
- PostMessage(hwndTClockMain, buttondown, wParam, lParam);
- buttondown = 0;
- return 0;
- case WM_RBUTTONUP:
- if(buttondown == WM_RBUTTONDOWN)
- PostMessage(hwndTClockMain, buttondown, wParam, lParam);
- buttondown = 0;
- break;
- case WM_MBUTTONUP:
- if(buttondown == WM_MBUTTONDOWN)
- PostMessage(hwndTClockMain, buttondown, wParam, lParam);
- buttondown = 0;
- return 0;
- // ダブルクリック
- case WM_LBUTTONDBLCLK:
- if(bStartMenuClock) return 0;
- case WM_RBUTTONDBLCLK:
- case WM_MBUTTONDBLCLK:
- PostMessage(hwndTClockMain, message, wParam, lParam);
- return 0;
- case WM_MOUSEMOVE:
- return 0;
- case WM_CONTEXTMENU: // 右クリックメニュー
- if(!hMenu)
- hMenu = CreateClockMenu();
- SetTimerMenu(hMenu);
- TrackPopupMenu(hMenu, TPM_LEFTALIGN,
- LOWORD(lParam), HIWORD(lParam), 0, hwnd, NULL);
- return 0;
- case WM_NCHITTEST: // oldWndProcに処理させない
- return DefWindowProc(hwnd, message, wParam, lParam);
- case WM_MOUSEACTIVATE:
- return MA_ACTIVATE;
- // ファイルのドロップ
- case WM_DROPFILES:
- PostMessage(hwndTClockMain, WM_DROPFILES, wParam, lParam);
- return 0;
- case WM_COMMAND:
- {
- WORD wID;
- wID = LOWORD(wParam);
- switch (wID)
- {
- case 100: // TClockのプロパティ
- PostMessage(hwndTClockMain, WM_USER+1, 0, 0);
- return 0;
- case 101: // TClockのヘルプ
- PostMessage(hwndTClockMain, WM_USER+5, 0, 0);
- return 0;
- case 102: // TClockの終了
- EndClock();
- return 0;
- case 103: // タイマー
- PostMessage(hwndTClockMain, WM_USER+6, (WPARAM)hwnd, 0);
- return 0;
- case 408:
- case 403:
- case 404:
- case 405:
- case 415:
- case 420:
- case 413:
- PostMessage(GetParent(GetParent(hwnd)), message,
- wParam, lParam);
- return 0;
- }
- if(wID >= 110)
- {
- StopTimer(wID - 110); return 0;
- }
- break;
- }
- case WM_NOTIFY: //ツールチップのテキスト表示
- {
- UINT code;
- code = ((LPNMHDR)lParam)->code;
- if(code == TTN_NEEDTEXT || code == TTN_NEEDTEXTW)
- {
- OnTooltipNeedText(code, lParam);
- return 0;
- }
- break;
- }
- case (WM_USER+1): // RefreshTClock() から送られる
- {
- BOOL b;
- ReadData(hwnd);
- SetStartButton(hwnd);
- SetStartMenu(hwnd);
- CreateClockDC(hwnd);
- b = GetMyRegLong(NULL, "DropFiles", FALSE);
- DragAcceptFiles(hwnd, b);
- InvalidateRect(hwnd, NULL, FALSE);
- PostMessage(GetParent(GetParent(hwnd)), WM_SIZE,
- SIZE_RESTORED, 0);
- InvalidateRect(GetParent(GetParent(hwndClock)), NULL, TRUE);
- return 0;
- }
- case (WM_USER+2): // BlinkTClock() から送られる
- {
- if(wParam) { if(nBlink == 0) nBlink = 4; }
- else nBlink = 2;
- return 0;
- }
-
- case (WM_USER+6): // タイマー開始
- StartTimer(lParam);
- return 0;
-
- case WM_WINDOWPOSCHANGING: // サイズ調整
- {
- LPWINDOWPOS pwp;
- if(bNoClock) break;
- pwp = (LPWINDOWPOS)lParam;
- if(IsWindowVisible(hwnd) && !(pwp->flags & SWP_NOSIZE))
- {
- int h;
- h = (int)HIWORD(OnCalcRect(hwnd));
- if(pwp->cy > h) pwp->cy = h;
- }
- break;
- }
- }
- /*
- {
- char s[80];
- wsprintf(s, "%X", message);
- WriteDebug(s);
- }
- */
- return CallWindowProc(oldWndProc, hwnd, message, wParam, lParam);
- }
-
- /*------------------------------------------------
- 設定の読み込みとデータの初期化
- --------------------------------------------------*/
- void ReadData(HWND hwnd)
- {
- char s[1024];
- char fontname[1024];
- int fontsize;
- LONG weight, italic;
-
- colfore = GetMyRegLong(NULL, "ForeColor",
- 0x80000000 | COLOR_BTNTEXT);
- colback = GetMyRegLong(NULL, "BackColor",
- 0x80000000 | COLOR_3DFACE);
-
- GetMyRegStr(NULL, "Font", fontname, "");
-
- fontsize = GetMyRegLong(NULL, "FontSize", 9);
- weight = GetMyRegLong(NULL, "Bold", 0);
- if(weight) weight = FW_BOLD;
- else weight = FW_NORMAL;
- italic = GetMyRegLong(NULL, "Italic", 0);
-
- if(hFon) DeleteObject(hFon);
- hFon = CreateMyFont(fontname, fontsize, weight, italic);
-
- dvpos = (int)(short)GetMyRegLong(NULL, "VertPos", 0);
- dheight = (int)(short)GetMyRegLong(NULL, "ClockHeight", 0);
-
- bNoClock = GetMyRegLong(NULL, "NoClock", FALSE);
-
- if(!GetMyRegStr(NULL, "Format", format, "") || !format[0])
- {
- bNoClock = TRUE;
- }
-
- bHour12 = GetMyRegLong(NULL, "Hour12", 0);
- bHourZero = GetMyRegLong(NULL, "HourZero", 0);
-
- bStartMenuClock = FALSE;
- if(GetMyRegLong(NULL, "StartButtonHide", FALSE))
- bStartMenuClock =
- GetMyRegLong(NULL, "StartMenuClock", FALSE);
-
- if(GetMyRegStr("Tooltip", "Tooltip", s, "") > 0)
- lstrcpyn(tooltip, s, 80);
- else tooltip[0] = 0;
-
- InitFormat(); // cf. format.c
- }
-
- /*------------------------------------------------
- 右クリック時のポップアップメニューの作成
- --------------------------------------------------*/
- HMENU CreateClockMenu(void)
- {
- HMENU hm;
- char entry[10];
- char s[11][80];
- int i;
-
- hm = CreatePopupMenu();
-
- for(i = 0; i < 11; i++)
- {
- wsprintf(entry, "%02d", i);
- GetMyRegStr("DLL", entry, s[i], "");
- }
-
- AppendMenu(hm, MF_STRING, 408, s[0]);
- AppendMenu(hm, MF_STRING, 403, s[1]);
- AppendMenu(hm, MF_STRING, 404, s[2]);
- AppendMenu(hm, MF_STRING, 405, s[3]);
- AppendMenu(hm, MF_SEPARATOR, 0, 0);
- AppendMenu(hm, MF_STRING, 415, s[4]);
- AppendMenu(hm, MF_SEPARATOR, 0, 0);
- if(!(GetVersion() & 0x80000000))
- {
- AppendMenu(hm, MF_STRING, 420, s[5]);
- AppendMenu(hm, MF_SEPARATOR, 0, 0);
- }
- AppendMenu(hm, MF_STRING, 413, s[6]);
- AppendMenu(hm, MF_SEPARATOR, 0, 0);
- AppendMenu(hm, MF_STRING, 103, s[7]);
- AppendTimerMenu(hm);
- AppendMenu(hm, MF_SEPARATOR, 0, 0);
- AppendMenu(hm, MF_STRING, 100, s[8]);
- AppendMenu(hm, MF_STRING, 101, s[9]);
- if(hhook)
- AppendMenu(hm, MF_STRING, 102, s[10]);
- SetMenuDefaultItem(hm, 408, FALSE);
- return hm;
- }
-
- /*------------------------------------------------
- ツールチップウィンドウの作成
- --------------------------------------------------*/
- void CreateTip(HWND hwnd)
- {
- TOOLINFO ti;
-
- hwndTip = CreateWindow(TOOLTIPS_CLASS, (LPSTR)NULL,
- TTS_ALWAYSTIP,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, hmod, NULL);
- if(!hwndTip) return;
-
- ti.cbSize = sizeof(TOOLINFO);
- ti.uFlags = 0;
- ti.hwnd = hwnd;
- ti.hinst = NULL;
- ti.uId = 1;
- ti.lpszText = LPSTR_TEXTCALLBACK;
- ti.rect.left = 0;
- ti.rect.top = 0;
- ti.rect.right = 480;
- ti.rect.bottom = 480;
-
- SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO)&ti);
- SendMessage(hwndTip, TTM_ACTIVATE, TRUE, 0);
- }
-
- /*------------------------------------------------
- 描画用メモリDCの作成
- --------------------------------------------------*/
- void CreateClockDC(HWND hwnd)
- {
- RECT rc;
- COLORREF col;
- HDC hdc;
-
- if(hdcClock) DeleteDC(hdcClock); hdcClock = NULL;
- if(hbmpClock) DeleteObject(hbmpClock); hbmpClock = NULL;
-
- if(bNoClock) return;
-
- GetClientRect(hwnd, &rc);
-
- hdc = GetDC(NULL);
-
- hdcClock = CreateCompatibleDC(hdc);
- if(!hdcClock) return;
- hbmpClock = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
- if(!hbmpClock) return;
- SelectObject(hdcClock, hbmpClock);
-
- SelectObject(hdcClock, hFon);
- SetBkMode(hdcClock, TRANSPARENT);
- SetTextAlign(hdcClock, TA_CENTER|TA_TOP);
- col = colfore;
- if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
- SetTextColor(hdcClock, col);
-
- ReleaseDC(NULL, hdc);
- }
-
- /*------------------------------------------------
- WM_TIMER の処理
- --------------------------------------------------*/
- void OnTimer(HWND hwnd)
- {
- SYSTEMTIME t;
- HDC hdc;
-
- GetLocalTime(&t);
- if(bNoClock) hdc = NULL;
- else if(!IsDispSecond(format) && // 秒表示なしのとき
- nBlink == 0 &&
- hourLast == (int)t.wHour && minuteLast == (int)t.wMinute)
- hdc = NULL;
- else hdc = GetDC(hwnd);
-
- // TClockウィンドウにアラーム処理させる
- if(hourLast != (int)t.wHour || minuteLast != (int)t.wMinute)
- PostMessage(hwndTClockMain, WM_USER+4,
- t.wMinute, MAKELONG(t.wHour, t.wDay));
-
- hourLast = t.wHour;
- minuteLast = t.wMinute;
-
- if(nBlink >= 3 && t.wMinute == 1) nBlink = 0;
-
- if(hdc)
- {
- DrawClockSub(hwnd, hdc, &t); //描画
- ReleaseDC(hwnd, hdc);
- }
-
- if(nBlink)
- {
- if(nBlink % 2) nBlink++;
- else nBlink--;
- }
-
- DoTimer(t.wMinute, t.wSecond); // タイマー
- }
-
- /*------------------------------------------------
- 時計の描画
- --------------------------------------------------*/
- void DrawClock(HWND hwnd, HDC hdc)
- {
- SYSTEMTIME t;
- GetLocalTime(&t);
- DrawClockSub(hwnd, hdc, &t);
- }
- void DrawClockSub(HWND hwnd, HDC hdc, SYSTEMTIME* pt)
- {
- COLORREF col;
- HBRUSH hbr;
- RECT rc;
- TEXTMETRIC tm;
- int hf, y;
- char s[1024], *p, *sp;
-
- if(!hdcClock) CreateClockDC(hwnd);
-
- if(!hdcClock || !hbmpClock) return;
-
- MakeFormat(s, pt, format);
-
- GetClientRect(hwnd, &rc);
- GetTextMetrics(hdcClock, &tm);
-
- if(nBlink == 0 || (nBlink % 2)) col = colfore;
- else col = colback;
- if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
- SetTextColor(hdcClock, col);
-
- if(nBlink == 0 || (nBlink % 2)) col = colback;
- else col = colfore;
- if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
- hbr = CreateSolidBrush(col);
- FillRect(hdcClock, &rc, hbr);
- DeleteObject(hbr);
-
- hf = tm.tmHeight - tm.tmInternalLeading;
- p = s;
- y = hf / 4 - tm.tmInternalLeading / 2;
- while(*p)
- {
- sp = p;
- while(*p && *p != 0x0d) p++;
- if(*p == 0x0d) { *p = 0; p += 2; }
- if(*p == 0 && sp == s)
- y = (rc.bottom - tm.tmHeight) / 2 - tm.tmInternalLeading / 4;
- TextOut(hdcClock, rc.right/2, y + dvpos, sp, strlen(sp));
- y += hf; if(*p) y += 2;
- }
- BitBlt(hdc, 0, 0, rc.right, rc.bottom, hdcClock, 0, 0, SRCCOPY);
- }
-
- /*------------------------------------------------
- 時計に必要なサイズを返す
- 戻り値:上位WORD 高さ 下位WORD 幅
- --------------------------------------------------*/
- LRESULT OnCalcRect(HWND hwnd)
- {
- SYSTEMTIME t;
- LRESULT w, h;
- HDC hdc;
- TEXTMETRIC tm;
- char s[1024], *p, *sp;
- SIZE sz;
- int hf;
-
- if(!IsWindowVisible(hwnd)) return 0;
-
- hdc = GetDC(hwnd);
-
- if(hFon) SelectObject(hdc, hFon);
- GetTextMetrics(hdc, &tm);
-
- t.wYear = 1996; t.wMonth = 12; t.wDay = 31;
- t.wDayOfWeek = 1; t.wHour = 11; t.wMinute = 30;
- t.wSecond = 30; t.wMilliseconds = 0;
- MakeFormat(s, &t, format);
-
- p = s; w = 0; h = 0;
- hf = tm.tmHeight - tm.tmInternalLeading;
- while(*p)
- {
- sp = p;
- while(*p && *p != 0x0d) p++;
- if(*p == 0x0d) { *p = 0; p += 2; }
- GetTextExtentPoint32(hdc, sp, strlen(sp), &sz);
- if(w < sz.cx) w = sz.cx;
- h += hf; if(*p) h += 2;
- }
- w += tm.tmAveCharWidth * 2;
- h += hf / 2 + dheight;
-
- ReleaseDC(hwnd, hdc);
-
- return (h << 16) + w;
- }
-
- /*------------------------------------------------
- ツールチップの表示
- --------------------------------------------------*/
- void OnTooltipNeedText(UINT code, LPARAM lParam)
- {
- char s[80];
-
- if(tooltip[0])
- strcpy(s, tooltip);
- else
- {
- strcpy(s, "TClock ");
- GetDateFormat(LOCALE_USER_DEFAULT,
- DATE_LONGDATE, NULL, NULL, s + 7, 80 - 7);
- }
- if(code == TTN_NEEDTEXT)
- strcpy(((LPTOOLTIPTEXT)lParam)->szText, s);
- else
- MultiByteToWideChar(CP_ACP, 0, s, -1,
- ((LPTOOLTIPTEXTW)lParam)->szText, 80);
- SetWindowPos(hwndTip, HWND_TOPMOST, 0, 0, 0, 0,
- SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
- }
-